#!/usr/bin/env python3

"""
Demo showing git tree visualization for bisect results
Shows how the tree structure helps understand bisect path
"""

import os
import sys
import tempfile
import subprocess

# Add bisect module path
sys.path.append(os.path.join(os.environ.get('LKP_SRC', '/home/shiptux/git/gitee/lkp-tests'), 'programs/bisect-py'))

from bisect_visualizer import BisectVisualizer


def create_demo_git_repo():
    """Create a demo git repository with branches and merges"""
    repo_dir = tempfile.mkdtemp(prefix="bisect_tree_demo_")
    print(f"Creating demo repository in: {repo_dir}")

    def git_cmd(cmd):
        """Execute git command in repo"""
        subprocess.run(f"git -C {repo_dir} {cmd}", shell=True, check=True,
                      stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)

    # Initialize repo
    git_cmd("init")
    git_cmd("config user.email 'test@example.com'")
    git_cmd("config user.name 'Test User'")

    # Create initial commits on master
    open(os.path.join(repo_dir, "file1.txt"), "w").write("Initial")
    git_cmd("add .")
    git_cmd("commit -m 'Initial commit'")
    initial_commit = subprocess.check_output(
        f"git -C {repo_dir} rev-parse HEAD", shell=True, text=True).strip()

    # More commits on master
    for i in range(3):
        open(os.path.join(repo_dir, f"file{i+2}.txt"), "w").write(f"Master content {i}")
        git_cmd(f"add .")
        git_cmd(f"commit -m 'Master commit {i+1}'")

    # Create feature branch from second commit
    git_cmd("checkout -b feature HEAD~2")

    # Add commits on feature branch
    for i in range(2):
        open(os.path.join(repo_dir, f"feature{i+1}.txt"), "w").write(f"Feature {i}")
        git_cmd(f"add .")
        git_cmd(f"commit -m 'Feature commit {i+1}'")

    # Merge feature into master
    git_cmd("checkout master")
    git_cmd("merge --no-ff feature -m 'Merge feature branch'")

    # More commits after merge
    for i in range(2):
        open(os.path.join(repo_dir, f"post_merge{i+1}.txt"), "w").write(f"Post merge {i}")
        git_cmd(f"add .")
        git_cmd(f"commit -m 'Post-merge commit {i+1}'")

    final_commit = subprocess.check_output(
        f"git -C {repo_dir} rev-parse HEAD", shell=True, text=True).strip()

    # Simulate bisect test results
    all_commits = subprocess.check_output(
        f"git -C {repo_dir} rev-list {initial_commit}..{final_commit}",
        shell=True, text=True
    ).strip().split('\n')

    # Simulate some tested commits with different status
    tested_commits = {}
    if len(all_commits) > 0:
        tested_commits[all_commits[0]] = 'bad'    # Latest is bad
    if len(all_commits) > 3:
        tested_commits[all_commits[3]] = 'bad'    # Middle is bad
    if len(all_commits) > 5:
        tested_commits[all_commits[5]] = 'good'   # Earlier is good
    if len(all_commits) > 6:
        tested_commits[all_commits[6]] = 'skip'   # One skipped

    # Also mark boundaries
    tested_commits[initial_commit] = 'good'
    tested_commits[final_commit] = 'bad'

    return repo_dir, initial_commit, final_commit, tested_commits, all_commits[3] if len(all_commits) > 3 else None


def main():
    """Run the git tree visualization demo"""
    print("=" * 100)
    print("Git Tree Visualization Demo for Bisect")
    print("=" * 100)
    print()

    # Create demo repository
    repo_dir, good_commit, bad_commit, tested_commits, first_bad = create_demo_git_repo()

    try:
        # Create visualizer
        visualizer = BisectVisualizer(width=100, height=20)

        # Show the normal git log first
        print("Standard git log output:")
        print("-" * 100)
        git_log = subprocess.check_output(
            f"git -C {repo_dir} log --oneline --graph {good_commit}..{bad_commit}",
            shell=True, text=True
        )
        print(git_log)

        # Show enhanced visualization with bisect results
        print("\n" + "=" * 100)
        print("Enhanced Bisect Tree Visualization:")
        print("-" * 100)
        tree_viz = visualizer.visualize_git_tree(
            repo_dir,
            good_commit,
            bad_commit,
            tested_commits,
            max_commits=50
        )
        print(tree_viz)

        # Show merge analysis
        if first_bad:
            print("\n" + "=" * 100)
            print("Merge Commit Analysis:")
            print("-" * 100)
            merge_analysis = visualizer.visualize_merge_analysis(
                repo_dir,
                first_bad,
                tested_commits
            )
            print(merge_analysis)

        # Explain the benefits
        print("\n" + "=" * 100)
        print("Benefits of Tree Visualization:")
        print("-" * 100)
        print("""
1. **Branch Structure**: Shows where branches diverged and merged
2. **Test Coverage**: Clearly marks which commits were tested ([+], [X], [?])
3. **Bisect Path**: Visualizes the binary search path through the tree
4. **Merge Analysis**: Identifies if regression came from a merge or specific branch
5. **Untested Areas**: Shows gaps in test coverage with [ ] markers

This helps developers:
- Understand complex git histories during bisect
- Identify which branch introduced a regression
- See if a merge conflict caused the issue
- Track bisect progress through non-linear history
        """)

    finally:
        # Cleanup
        import shutil
        shutil.rmtree(repo_dir, ignore_errors=True)
        print(f"\nCleaned up demo repository: {repo_dir}")


if __name__ == "__main__":
    main()